package us.icitap.commandcenter.ui.supervisor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.vaadin.artur.icepush.ICEPush;

import us.icitap.commandcenter.CommandCenterUI;
import us.icitap.commandcenter.business.Result;
import us.icitap.commandcenter.business.ejb.dao.Expression;
import us.icitap.commandcenter.business.ejb.dao.Operator;
import us.icitap.commandcenter.business.ejb.persistence.Call;
import us.icitap.commandcenter.business.ejb.persistence.CallStatusEnum;
import us.icitap.commandcenter.ui.custom.CustColumnGenerator;
import us.icitap.commandcenter.ui.custom.CustTable;
import us.icitap.commandcenter.ui.custom.CustVerticalLayout;
import us.icitap.commandcenter.ui.dispatcher.CallMessage;
import us.icitap.commandcenter.utils.HandleNotification;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;


public class SupervisorVerticalLayout extends CustVerticalLayout implements  MessageListener {

	private ICEPush pusher = new ICEPush();
	 
	private Connection connection;
	private Session session;

	private CustTable table;
	
	private final String lRedText = "TELEFONATA TE REJA: " ;
	private final String lYellowText = "NE PRITJE PER TU VERIFIKUAR: " ;
	private final String lGreenText = "TELEFONATA TE VERIFKUARA: ";
	private final String lGreenUNText = "NUMRA UNIK: ";
	
	
	private final Label lRed = new Label(lRedText + 0);
	private final Label lYellow = new Label(lYellowText + 0);
	private final Label lGreen = new Label(lGreenText + 0);
	private final Label lGreenUN = new Label(lGreenUNText + 0);
	
	private Integer redCount = 0;
	private Integer yellowCount = 0;
	private Integer greenCount = 0;
	private Long greenUNCount = 0l;
	
	
	private List<Call> callList = Collections.synchronizedList(new ArrayList<Call>()); 
	
	final BeanItemContainer<Call> beans  = new BeanItemContainer<Call>(Call.class);

	public SupervisorVerticalLayout() {
	
		table = new CustTable(null,beans);
		 
		table.setVisibleColumns(new Object[]{"caller","recordDate", "callReason", "address", "description", "mainDispatcher"});
		table.setColumnHeaders(new String[]{"TELEFONUESI", "DT. REGJ.", "ARSYEJA E TELEFONATES", "ADRESA", "PERSHKRIMI", "ZONA E MBULIMIT"});
		table.addGeneratedColumn("callReason", CustColumnGenerator.callReasonColumnGenerator);
		table.addGeneratedColumn("mainDispatcher", CustColumnGenerator.dispatcherColumnGenerator);
		table.setPageLength(30);
		table.setWidth("1000px");
		
		table.setColumnWidth("caller", 300);
		table.setColumnWidth("address", 200);
		table.setColumnWidth("description", 300);
		table.setColumnWidth("mainDispatcher", 400);
		table.setImmediate(true);
		
		table.setCellStyleGenerator(new Table.CellStyleGenerator() {
			
			@Override
			public String getStyle(Table source, Object itemId,
					Object propertyId) {
				if(propertyId == null){
					if(((Call)itemId).getActualStatus().equals(CallStatusEnum.N))
						return "red";
					else if(((Call)itemId).getActualStatus().equals(CallStatusEnum.WV))
						return "yellow";
					else if(((Call)itemId).getActualStatus().equals(CallStatusEnum.V))
						return "green";
				}
				return null;
			}
		});
		
		table.setItemDescriptionGenerator(new ItemDescriptionGenerator() {
			
			@Override
			public String generateDescription(Component source, Object itemId,
					Object propertyId) {
				Call c = (Call)itemId;
				return c.getToolTip();
				
				
			}
		});
		
		this.updateLabels();
		
		table.setSelectable(true);
		this.addComponent(this.getTableHeader());
		this.addComponent(table);
		this.setSizeUndefined();
		
		
		table.setImmediate(true);
		
		this.addExtension(pusher);
		
		
		this.initTable();
		startListening();
	}
	
	
	public void initTable(){
		List<Expression> exp = new ArrayList<Expression>();
		
		exp.add(new Expression("commandCenter", CommandCenterUI.getUser().getCommandCenter(), Operator.EQ));
		exp.add(new Expression("actualStatus", CallStatusEnum.N, Operator.EQ));
		
		Result<List<Call>> result = CommandCenterUI.appStatelessBean.getInitialNewCallList(CommandCenterUI.getUser().getCommandCenter().getActiveDispatcherList());
		
		
		if(result.isSucceeded()){
			callList.addAll(result.getObject());
			redCount = result.getObject().size();
		}
		else
			CommandCenterUI.LOG.logp(Level.SEVERE,"SupervisorVerticalLayout","initTable()", result.getMessage());
		
		
		result =  CommandCenterUI.appStatelessBean.getWvCallList(CommandCenterUI.getUser().getCommandCenter().getActiveDispatcherList());
	
		if(result.isSucceeded()){
			callList.addAll(result.getObject());
			yellowCount = result.getObject().size();
		}
		else
			CommandCenterUI.LOG.logp(Level.SEVERE,"SupervisorVerticalLayout","initTable()", result.getMessage());
		
		

		result = CommandCenterUI.appStatelessBean.getClosedCallList(CommandCenterUI.getUser().getCommandCenter().getActiveDispatcherList());
		
		if(result.isSucceeded()){
			callList.addAll(result.getObject());
			greenCount = result.getObject().size();
		}
		else
			CommandCenterUI.LOG.logp(Level.SEVERE,"SupervisorVerticalLayout","initTable()", result.getMessage());
		
	
		this.beans.addAll(callList);
//		Result<Long> resultUN =  CommandCenterUI.persistenceBean.findUniqueNumberTotal(appUser.getCommandCenter(), shiftLimits[0], new Date());
//		if(resultUN.isSucceeded()){
//			greenUNCount =resultUN.getObject();
//			
//		}
		this.updateTable();
	}
	
	public void startListening(){
	    try{
	    	connection =CommandCenterUI.appStatelessBean.getConnectionFactory().createConnection();
	    	session= connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

	    	Destination dest = session.createTopic("SUPERVISOR" + CommandCenterUI.getUser().getCommandCenter().getId());
	    	MessageConsumer messageConsumer = session.createConsumer(dest);
	    	messageConsumer.setMessageListener(this);
	    	connection.start();

	    }
	    catch (JMSException e)
	    {
	      e.printStackTrace();
	    }
	   
	}
	@Override
	public void onMessage(Message message) {
		ObjectMessage objectMessage = (ObjectMessage)message;
		System.out.println(objectMessage.getClass().getName());
		try {
			
			CallMessage callMessage  = (CallMessage) objectMessage.getObject();
			this.processCall(callMessage.getCall(), callMessage.getPrevoiusStatus());
			if(callMessage.getPrevoiusStatus() == null)
				HandleNotification.showInfoOnScreen("Erdhi nje telefonate e re");
			else
				HandleNotification.showInfoOnScreen("Nje telefonate u ndryshua");
			
			
			
			pusher.push();
	
		} catch (Exception e) {
			e.printStackTrace();
		}
	
		
	}
	
	private void updateTable(){
		boolean[] order = {false};
		table.sort(new Object[]{"recordDate"}, order);
		updateLabels();
		
	}
	
	public void updateLabels(){
		this.lRed.setValue(this.lRedText + this.redCount);
		this.lYellow.setValue(this.lYellowText + this.yellowCount);
		this.lGreen.setValue(lGreenText + this.greenCount);
		this.lGreenUN.setValue(lGreenUNText + this.greenUNCount);
	}
	

	private HorizontalLayout getTableHeader(){
		
		lRed.addStyleName("boldLabel");
		lYellow.addStyleName("boldLabel");
		lGreen.addStyleName("boldLabel");
		lGreenUN.addStyleName("boldLabel");
		
		final HorizontalLayout hl = new HorizontalLayout();
		
		final VerticalLayout vlRed = new VerticalLayout();
		vlRed.setWidth("15px");vlRed.setHeight("15px");
		vlRed.addStyleName("red");
		
		final VerticalLayout vlYellow = new VerticalLayout();
		vlYellow.setWidth("15px");vlYellow.setHeight("15px");
		vlYellow.addStyleName("yellow");
		
		final VerticalLayout vlGreen = new VerticalLayout();
		vlGreen.setWidth("15px");vlGreen.setHeight("15px");
		vlGreen.addStyleName("green");
		
		final VerticalLayout vlGreenUN = new VerticalLayout();
		vlGreenUN.setWidth("15px");vlGreenUN.setHeight("15px");
		vlGreenUN.addStyleName("green");
		
		final HorizontalLayout hlRed = new HorizontalLayout();
		
		hlRed.addComponent(vlRed);
		hlRed.addComponent(lRed);
		hl.addComponent(hlRed);
		
		final HorizontalLayout hlYellow = new HorizontalLayout();
		hlYellow.addComponent(vlYellow);
		hlYellow.addComponent(lYellow);
		hl.addComponent(hlYellow);
		
		final HorizontalLayout hlGreen = new HorizontalLayout();
		hlGreen.addComponent(vlGreen);
		hlGreen.addComponent(lGreen);
		hl.addComponent(hlGreen);
		
		final HorizontalLayout hlGreenUN = new HorizontalLayout();
		hlGreenUN.addComponent(vlGreenUN);
		hlGreenUN.addComponent(lGreenUN);
		hl.addComponent(hlGreenUN);
		
		hl.setSpacing(true);
		hl.setSizeFull();
		hl.setMargin(true);
		return hl;
		
	}

	public void removeCallFromList(Call call, CallStatusEnum prevoiusStatus){
		this.beans.removeItem(call);
		if(CallStatusEnum.N.equals(prevoiusStatus)){
			redCount -= 1;
		}
		else if (CallStatusEnum.WV.equals(prevoiusStatus)){
			yellowCount -= 1;
			System.out.println("test " + yellowCount);
		}
		else if (CallStatusEnum.V.equals(prevoiusStatus)){
			greenCount -= 1;
		}
	}
	


	public void processCall(Call call, CallStatusEnum previousStatus) {
		if(previousStatus == null){
			//Telefonate e re
			beans.addBean(call);
			redCount += 1;
			updateTable();
			return;
		}
		if(call.getActualStatus().equals(previousStatus)){
			
			//Telefonates nuk i ka ndryshuar statusi por vetem eshte update-uar me info gjate verifikimit
			beans.removeItem(call);
			beans.addBean(call);
			updateTable();
			return;
		}
		
		// Telefonata nuk eshte e re dhe i ka ndryshuar statusi
		
		this.removeCallFromList(call, previousStatus);
		
		beans.addBean(call);

		if(call.getActualStatus().equals(CallStatusEnum.N)){
			redCount += 1;
		}
		else if(call.getActualStatus().equals(CallStatusEnum.WV)){
			yellowCount += 1;
		}
		else if(call.getActualStatus().equals(CallStatusEnum.V)){
			greenCount += 1;
			if(call.getUniqueNumber() != null){
				this.greenUNCount += 1;
			}
		}
		
		updateTable();
		
		
	}
	
	
	@Override
	public void detach() {
		CommandCenterUI.LOG.info("SupervisorVerticalLayout.detach()");
		try {
			this.session.close();
			this.connection.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		super.detach();
	}
}
